package py.fpuna.ii.electiva2.client.clases;

import py.fpuna.ii.electiva2.client.model.ClienteModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import java.util.Iterator;
import java.util.List;
import py.fpuna.ii.electiva2.client.GWTService;
import py.fpuna.ii.electiva2.client.GWTServiceAsync;

/**
 *
 * @author sebastian
 */
public class ABMClientes extends VerticalPanel{

    ABMClientes miABM;
    FlexTable datos = new FlexTable();
    TextBox textNombre = new TextBox();
    TextBox textApellido = new TextBox();
    TextBox textCedula = new TextBox();
    TextBox textDireccion = new TextBox();
    TextBox textRuc = new TextBox();
    Button guardar = new Button("Agregar");
    Button modificar = new Button("Modificar");
    private Label resultado = new Label();


    private HorizontalPanel buscador = new HorizontalPanel();
    private Label buscarClientName = new Label("Buscar por nombre de Cliente");
    private TextBox buscarClient = new TextBox();
    private Button botonBuscar = new Button("Buscar");

    FlexTable tablaClient = new FlexTable();

    Integer k;  //identificador de la clave del cliente usada en los metodos finales

    public ABMClientes()
    {
        datos.setText(0, 0, "Nombre");
        datos.setText(1, 0, "Apellido");
        datos.setText(2, 0, "Cedula");
        datos.setText(3, 0, "Direccion");
        datos.setText(4, 0, "Ruc");
        datos.setWidget(0,1, textNombre);
        datos.setWidget(1,1, textApellido);
        datos.setWidget(2,1, textCedula);
        datos.setWidget(3,1, this.textDireccion);
        datos.setWidget(4,1, this.textRuc);

        miABM = this;   //me referencio a mi mismo
        miABM.add(datos);
        miABM.setSpacing(10);
        miABM.add(guardar);
        modificar.setVisible(false);
        miABM.add(modificar);

        miABM.add(resultado);

        buscador.setSpacing(5);
        buscador.add(buscarClientName);
        buscador.add(buscarClient);
        buscador.add(botonBuscar);
        miABM.add(buscador);

        mostrarTabla(); //reconstruye la tabla

        guardar.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                agregarCliente();
            }
        });

        botonBuscar.addClickHandler(new ClickHandler(){
            public void onClick(ClickEvent event) {
                buscarCliente(buscarClient.getText());
            }


        });

    }

    public static GWTServiceAsync getService() {
        // Create the client proxy. Note that although you are creating the
        // service interface proper, you cast the result to the asynchronous
        // version of the interface. The cast is always safe because the
        // generated proxy implements the asynchronous interface automatically.

        return GWT.create(GWTService.class);
    }

    private void buscarCliente(String nomCli){
        miABM.remove(tablaClient);
        tablaClient = new FlexTable();

        final AsyncCallback< List<ClienteModel> > callback5 = new AsyncCallback< List<ClienteModel> >() {
            public void onSuccess(List<ClienteModel> result) {
                tablaClient.setWidth("800px");
                tablaClient.setBorderWidth(1);
                tablaClient.setText(0, 0, "Nombre");
                tablaClient.setText(0, 1, "Apellido");
                tablaClient.setText(0, 2, "Cedula");
                tablaClient.setText(0, 3, "Direccion");
                tablaClient.setText(0, 4, "Ruc");
                tablaClient.setText(0, 5, "Modificar");
                tablaClient.setText(0, 6, "Eliminar");
                if (result == null){
                    resultado.setText("No hay datos en la tabla");
                }else{  //recibi datos en result

                    Iterator <ClienteModel> clientIt = result.iterator();
                    int f = 1;

                    while(clientIt.hasNext()){
                        ClienteModel clientM = clientIt.next();
                        tablaClient.setWidget(f, 0, new Label(clientM.getClieNombre()));
                        tablaClient.setWidget(f, 1, new Label(clientM.getClieApellido()));
                        tablaClient.setWidget(f, 2, new Label(clientM.getClieCi()));
                        tablaClient.setWidget(f, 3, new Label(clientM.getClieDireccion()));
                        tablaClient.setWidget(f, 4, new Label(clientM.getClieRuc()));

                        final int key = clientM.getClieCodigo();
                        final ClienteModel cM = clientM; //prepara un cliente para modificarlo

                        tablaClient.setWidget(f, 5, new Button("Modificar", new ClickHandler() {
                                                        public void onClick(ClickEvent event) {
                                                            modificarCliente(key, cM);
                                                        }
                                                    }));
                        tablaClient.setWidget(f, 6, new Button("Eliminar",  new ClickHandler() {
                                                        public void onClick(ClickEvent event) {
                                                            eliminarCliente(key);
                                                        }
                                                    }));
                        f++;
                    }
                }

                miABM.add(tablaClient); //cargo la tabla en mi mismo
            }

            public void onFailure(Throwable caught) {
                resultado.setText("Fallo la comunicacion");
            }
        };

        getService().listarClientesEncontrados(nomCli, callback5);

    }




    /**
     * agrega un cliente a la BD
     */
    private void agregarCliente()
    {
        String nom = this.textNombre.getText();
        String ape = this.textApellido.getText();
        String ced = this.textCedula.getText();
        String dir = this.textDireccion.getText();
        String ruc = this.textRuc.getText();

        if ( nom.compareTo("") == 0 ||
             ape.compareTo("")== 0 ||
             ced.compareTo("") == 0 ||
             dir.compareTo("") == 0 ||
             ruc.compareTo("") == 0)
        {
            Window.setTitle("TAREA GWT - EJB");
            Window.alert("Debe cargar todos los campos");
            textNombre.setFocus(true);
            return;
        }

        ClienteModel client = new ClienteModel();
        client.setClieNombre(nom);
        client.setClieApellido(ape);
        client.setClieCi(ced);
        client.setClieDireccion(dir);
        client.setClieRuc(ruc);

        // Create an asynchronous callback to handle the result.
        final AsyncCallback<String> callback = new AsyncCallback<String>() {
            public void onSuccess(String result) {
                if (result.equalsIgnoreCase("true")){

                      //le muestro lo que puede modificar
                    textNombre.setText("");
                    textApellido.setText("");
                    textCedula.setText("");
                    textDireccion.setText("");
                    textRuc.setText("");


                     Window.alert("Registro guardado satisfactoriamente");
                    mostrarTabla();
                }else{
                    Window.alert("Error. El registro no ha sido guardado");
                }
            }
            public void onFailure(Throwable caught) {
                Window.alert("Error. Ingrese palabras mas cortas en los campos");
            }
        };

        getService().guardarCliente(client, callback);

    }

    /**
     * muestra la tabla, contruyendola a partir de los datos
     * de la BD
     */
    private void mostrarTabla(){
        miABM.remove(tablaClient);
        tablaClient = new FlexTable();

        final AsyncCallback< List<ClienteModel> > callback2 = new AsyncCallback< List<ClienteModel> >() {
            public void onSuccess(List<ClienteModel> result) {
                tablaClient.setWidth("800px");
                tablaClient.setBorderWidth(1);
                tablaClient.setText(0, 0, "Nombre");
                tablaClient.setText(0, 1, "Apellido");
                tablaClient.setText(0, 2, "Cedula");
                tablaClient.setText(0, 3, "Direccion");
                tablaClient.setText(0, 4, "Ruc");
                tablaClient.setText(0, 5, "Modificar");
                tablaClient.setText(0, 6, "Eliminar");
                if (result == null){
                    resultado.setText("No hay datos en la tabla");
                }else{  //recibi datos en result

                    Iterator <ClienteModel> clientIt = result.iterator();
                    int f = 1;

                    while(clientIt.hasNext()){
                        ClienteModel clientM = clientIt.next();
                        tablaClient.setWidget(f, 0, new Label(clientM.getClieNombre()));
                        tablaClient.setWidget(f, 1, new Label(clientM.getClieApellido()));
                        tablaClient.setWidget(f, 2, new Label(clientM.getClieCi()));
                        tablaClient.setWidget(f, 3, new Label(clientM.getClieDireccion()));
                        tablaClient.setWidget(f, 4, new Label(clientM.getClieRuc()));

                        final int key = clientM.getClieCodigo();
                        final ClienteModel cM = clientM; //prepara un cliente para modificarlo
                        
                        tablaClient.setWidget(f, 5, new Button("Modificar", new ClickHandler() {
                                                        public void onClick(ClickEvent event) {
                                                            modificarCliente(key, cM);
                                                        }
                                                    }));
                        tablaClient.setWidget(f, 6, new Button("Eliminar",  new ClickHandler() {
                                                        public void onClick(ClickEvent event) {
                                                            eliminarCliente(key);
                                                        }
                                                    }));
                        f++;
                    }
                }
                
                miABM.add(tablaClient); //cargo la tabla en mi mismo
            }

            public void onFailure(Throwable caught) {
                resultado.setText("Fallo la comunicacion");
            }
        };

        getService().listarClientes(callback2);
    }


    /**
     * modifica los datos del cliente seleccionado
     * @param client: objeto ClienteModel que representa al modificado
     */
    private void modificarCliente(Integer clave, ClienteModel client){

        k = clave; //identificador del cliente cargado en var auxiliar

        //le muestro lo que puede modificar
        this.textNombre.setText(client.getClieNombre());
        this.textApellido.setText(client.getClieApellido());
        this.textCedula.setText(client.getClieCi());
        this.textDireccion.setText(client.getClieDireccion());
        this.textRuc.setText(client.getClieRuc());

        // Create an asynchronous callback to handle the result.
        final AsyncCallback<String> callback4 = new AsyncCallback<String>() {
            public void onSuccess(String result) {
                if (result.equalsIgnoreCase("modificado")){

                    k = null;   //ya no uso mas k, entoncs limpio
                    modificar.setVisible(false);
                    guardar.setVisible(true);

                    //limpio todo lo que use
                    textNombre.setText("");
                    textApellido.setText("");
                    textCedula.setText("");
                    textDireccion.setText("");
                    textRuc.setText("");

                    Window.alert("Registro modificado satisfactoriamente");
                    mostrarTabla();
                    
                }else{
                    Window.alert("Error. El registro no ha sido modificado");
                }
            }
            public void onFailure(Throwable caught) {
                Window.alert("Error. Ingrese palabras mas cortas en los campos");
            }
        };

        //oculto el boton guardar y muestro el modificar
        guardar.setVisible(false);
        modificar.setVisible(true);

        //coloco la llamdada remota en el boton modificar
        modificar.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {

                //guardo lo que modifico
                String nom = textNombre.getText();
                String ape = textApellido.getText();
                String ced = textCedula.getText();
                String dir = textDireccion.getText();
                String ruc = textRuc.getText();

                //verifico que todo este cargado
                if ( nom.compareTo("") == 0 ||
                     ape.compareTo("")== 0 ||
                     ced.compareTo("") == 0 ||
                     dir.compareTo("") == 0 ||
                     ruc.compareTo("") == 0)
                {
                    Window.setTitle("TAREA GWT - EJB");
                    Window.alert("Debe cargar todos los campos D; ");
                    textNombre.setFocus(true);
                    return;
                }

                //actualizo los datos del cliente guardandolos en uno nuevo
                ClienteModel clientM = new ClienteModel();
                clientM.setClieNombre(nom);
                clientM.setClieApellido(ape);
                clientM.setClieCi(ced);
                clientM.setClieDireccion(dir);
                clientM.setClieRuc(ruc);

                //le paso el identificador el cliente y lo q cambio
                getService().modificarCliente(k, clientM, callback4);
            }
        });

        
    }


    /**
     * elimina un cliente de la lista y de la BD
     * @param codigo: identificador del cliente a ser eliminado
     */
    private void eliminarCliente(Integer codigo){

        // Create an asynchronous callback to handle the result.
        final AsyncCallback<String> callback3 = new AsyncCallback<String>() {
            public void onSuccess(String result) {
                mostrarTabla();
                Window.alert("Registro eliminado satisfactoriamente");
            }

            public void onFailure(Throwable caught) {
                Window.alert("Error.No se ha podido eliminar el registro porque esta siendo utilizado");
            }
        };

        getService().eliminarCliente(codigo, callback3);
    }

}
